package com.ruoyi.system.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.db.sql.Order;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.domain.SysHotelRoom;
import com.ruoyi.system.domain.dto.DashboardItemDto;
import com.ruoyi.system.domain.vo.DashboardTrendResp;
import com.ruoyi.system.domain.vo.DashboardTypeResp;
import com.ruoyi.system.domain.vo.SysOrderResp;
import com.ruoyi.system.enums.HotelRoomTypEnum;
import com.ruoyi.system.enums.OrderStatusEnum;
import com.ruoyi.system.enums.PayStatusEnum;
import com.ruoyi.system.enums.RoomStatusEnum;
import com.ruoyi.system.service.ISysHotelRoomService;
import com.ruoyi.system.service.ISysHotelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.SysOrderMapper;
import com.ruoyi.system.domain.SysOrder;
import com.ruoyi.system.service.ISysOrderService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 订单Service业务层处理
 * 
 * @author dht
 * @date 2025-04-28
 */
@Service
public class SysOrderServiceImpl implements ISysOrderService 
{
    @Autowired
    private SysOrderMapper sysOrderMapper;
    @Autowired
    private ISysHotelService hotelService;
    @Autowired
    private ISysHotelRoomService hotelRoomService;

    /**
     * 查询订单
     * 
     * @param orderId 订单主键
     * @return 订单
     */
    @Override
    public SysOrder selectSysOrderByOrderId(Long orderId)
    {
        return sysOrderMapper.selectSysOrderByOrderId(orderId);
    }

    /**
     * 查询订单列表
     * 
     * @param sysOrder 订单
     * @return 订单
     */
    @Override
    public List<SysOrderResp> selectSysOrderList(SysOrder sysOrder)
    {
        return sysOrderMapper.selectSysOrderList(sysOrder)
                .stream().map(item -> {
                    SysOrderResp resp = BeanUtil.copyProperties(item, SysOrderResp.class);
                    resp.setHotelName(hotelService.selectSysHotelByHotelId(resp.getHotelId()).getName());
                    resp.setHotelRoomTypeName(HotelRoomTypEnum.getByKey(Integer.parseInt(item.getHotelRoomType().toString())));
                    if (Objects.nonNull(item.getPayType())) {
                        resp.setPayTypeName(PayStatusEnum.getByKey(item.getPayType()));
                    }
                    return resp;
                }).collect(Collectors.toList());
    }

    /**
     * 新增订单
     * 
     * @param sysOrder 订单
     * @return 结果
     */
    @Override
    @Transactional
    public int insertSysOrder(SysOrder sysOrder)
    {
        long diffInMillis = sysOrder.getOutDate().getTime() - sysOrder.getInDate().getTime();
        long daysBetween = diffInMillis / (1000 * 60 * 60 * 24);
        SysHotelRoom hotelRoom = hotelRoomService.selectSysHotelRoomByHotelIdAndType(sysOrder.getHotelId(), sysOrder.getHotelRoomType());
        if (Objects.isNull(hotelRoom)) {
            throw new GlobalException("房型不存在");
        }
        if (hotelRoom.getRemainNumber().equals(0L)) {
            throw new GlobalException("剩余房间不足");
        }
        sysOrder.setTotalAmount(hotelRoom.getPrice().multiply(BigDecimal.valueOf(daysBetween)));
        sysOrder.setCreateTime(DateUtils.getNowDate());
        sysOrder.setUserId(SecurityUtils.getUserId());
        sysOrder.setStatus(OrderStatusEnum.OBLIGATION.getKey());
        sysOrder.setRoomStatus(RoomStatusEnum.DONE.getKey());
        int i = sysOrderMapper.insertSysOrder(sysOrder);
        // 更新房间信息
        hotelRoom.setRemainNumber(hotelRoom.getRemainNumber() - 1);
        hotelRoomService.updateSysHotelRoom(hotelRoom);
        return i;
    }

    /**
     * 修改订单
     * 
     * @param sysOrder 订单
     * @return 结果
     */
    @Override
    public int updateSysOrder(SysOrder sysOrder)
    {
        sysOrder.setUpdateTime(DateUtils.getNowDate());
        return sysOrderMapper.updateSysOrder(sysOrder);
    }

    /**
     * 批量删除订单
     * 
     * @param orderIds 需要删除的订单主键
     * @return 结果
     */
    @Override
    public int deleteSysOrderByOrderIds(Long[] orderIds)
    {
        return sysOrderMapper.deleteSysOrderByOrderIds(orderIds);
    }

    /**
     * 删除订单信息
     * 
     * @param orderId 订单主键
     * @return 结果
     */
    @Override
    public int deleteSysOrderByOrderId(Long orderId)
    {
        return sysOrderMapper.deleteSysOrderByOrderId(orderId);
    }

    @Override
    public List<SysOrderResp> getUserOrderList(SysOrder sysOrder) {
        sysOrder.setUserId(SecurityUtils.getUserId());
        return sysOrderMapper.selectSysOrderList(sysOrder)
                .stream().map(item -> {
                    SysOrderResp resp = BeanUtil.copyProperties(item, SysOrderResp.class);
                    resp.setHotelName(hotelService.selectSysHotelByHotelId(resp.getHotelId()).getName());
                    resp.setHotelRoomTypeName(HotelRoomTypEnum.getByKey(Integer.parseInt(item.getHotelRoomType().toString())));
                    if (Objects.nonNull(item.getPayType())) {
                        resp.setPayTypeName(PayStatusEnum.getByKey(item.getPayType()));
                    }
                    return resp;
                }).collect(Collectors.toList());
    }

    @Override
    public int selectCount() {
        return sysOrderMapper.selectCount();
    }

    @Override
    public DashboardTrendResp selectOrderTrendList() {
        List<Date> dates = new ArrayList<>();
        // 去掉时分秒
        Date date =  DateUtil.beginOfDay(new Date());
        int days = 7;
        for(int i = 0; i < days; i++) {
            dates.add(DateUtil.offsetDay(date, -1 * i));
        }

        Map<Date, Integer> groupDateMap = sysOrderMapper.getCountGroupByDate(dates)
                .stream()
                .map(item -> new DashboardItemDto(DateUtil.beginOfDay(item.getDate()), item.getCount()))
                .collect(Collectors.toMap(DashboardItemDto::getDate, DashboardItemDto::getCount));

        List<String> xData = new ArrayList<>();
        List<Integer> yData = new ArrayList<>();
        dates.forEach(item -> {
            xData.add(DateUtil.formatDate(item));
            yData.add(groupDateMap.getOrDefault(item, 0));
        });

        return new DashboardTrendResp(xData, yData);
    }

    @Override
    public List<DashboardTypeResp> selectOrderTypeList() {
        return Arrays.stream(PayStatusEnum.values()).map(item -> {
            DashboardTypeResp res = new DashboardTypeResp();
            res.setName(item.getValue());
            res.setValue(sysOrderMapper.getCountByPayType(item.getKey()));
            return res;
        }).collect(Collectors.toList());
    }


    @Override
    @Transactional
    public int frontFeedback(SysOrder sysOrder) {
        SysOrder find = selectSysOrderByOrderId(sysOrder.getOrderId());
        SysHotelRoom hotelRoom = hotelRoomService.selectSysHotelRoomByHotelIdAndType(sysOrder.getHotelId(), sysOrder.getHotelRoomType());
        hotelRoom.setRemainNumber(hotelRoom.getRemainNumber() +  1);
        find.setRoomStatus(RoomStatusEnum.NONE.getKey());
        int i = sysOrderMapper.updateSysOrder(find);
        int j = hotelRoomService.updateSysHotelRoom(hotelRoom);
        return i + j;
    }
}
